package com.ruoyi.system.service.impl;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysWater;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysWaterMenu;
import com.ruoyi.system.domain.SysRoleDept;
import com.ruoyi.system.domain.SysUserWater;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ISysWaterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 水泵业务层处理
 *
 * @author ruoyi
 */
@Service
public class SysWaterServiceImpl implements ISysWaterService
{
    @Autowired
    private SysWaterDeptMapper waterDeptMapper;

    @Autowired
    private SysWaterMenuMapper waterMenuMapper;

    @Autowired
    private SysWaterMapper waterMapper;

    @Autowired
    private SysUserWaterMapper userWaterMapper;

    @Autowired
    private SysRoleDeptMapper roleDeptMapper;

    @Autowired
    private SysAerationMapper aerationMapper;

    @Autowired
    private SysAerationMenuMapper aerationMenuMapper;

    @Autowired
    private SysAerationDeptMapper aerationDeptMapper;

    /**
     * 根据条件分页查询水泵数据
     *
     * @param sysWater 水泵信息
     * @return 水泵数据集合信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<SysWater> selectSysWaterList(SysWater sysWater)
    {
        return waterMapper.selectWaterList(sysWater);
    }

    /**
     * 根据用户ID查询水泵
     *
     * @param userId 用户ID
     * @return 水泵列表
     */
    @Override
    public List<SysWater> selectSysWatersByUserId(Long userId)
    {
        List<SysWater> userAerations = waterMapper.selectWaterPermissionByUserId(userId);
        List<SysWater> sysWaters = selectWaterAll();
        for (SysWater sysWater : sysWaters)
        {
            for (SysWater userWater : userAerations)
            {
                if (sysWater.getWaterId().longValue() == userWater.getWaterId().longValue())
                {
                    sysWater.setFlag(true);
                    break;
                }
            }
        }
        return sysWaters;
    }

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectSysWaterPermissionByUserId(Long userId)
    {
        List<SysWater> perms = waterMapper.selectWaterPermissionByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (SysWater perm : perms)
        {
            if (StringUtils.isNotNull(perm))
            {
                permsSet.addAll(Arrays.asList(perm.getWaterKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    /**
     * 查询所有水泵
     *
     * @return 水泵列表
     */
    @Override
    public List<SysWater> selectWaterAll()
    {
        return SpringUtils.getAopProxy(this).selectSysWaterList(new SysWater());
    }

    /**
     * 根据用户ID获取水泵选择框列表
     *
     * @param userId 用户ID
     * @return 选中水泵ID列表
     */
    @Override
    public List<Long> selectWaterListByUserId(Long userId)
    {
        return waterMapper.selectWaterListByUserId(userId);
    }

    /**
     * 通过水泵ID查询水泵
     *
     * @param waterId 水泵ID
     * @return 水泵对象信息
     */
    @Override
    public SysWater selectWaterById(Long waterId)
    {
        return waterMapper.selectWaterById(waterId);
    }

    /**
     * 校验水泵名称是否唯一
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    public String checkWaterNameUnique(SysWater sysWater)
    {
        Long waterId = StringUtils.isNull(sysWater.getWaterId()) ? -1L : sysWater.getWaterId();
        SysWater info = waterMapper.checkWaterNameUnique(sysWater.getWaterName());
        if (StringUtils.isNotNull(info) && info.getWaterId().longValue() != waterId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验水泵权限是否唯一
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    public String checkWaterKeyUnique(SysWater sysWater)
    {
        Long waterId = StringUtils.isNull(sysWater.getWaterId()) ? -1L : sysWater.getWaterId();
        SysWater info = waterMapper.checkWaterKeyUnique(sysWater.getWaterKey());
        if (StringUtils.isNotNull(info) && info.getWaterId().longValue() != waterId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验水泵是否允许操作
     *
     * @param sysWater 水泵信息
     */
    @Override
    public void checkWaterAllowed(SysWater sysWater)
    {
        if (StringUtils.isNotNull(sysWater.getWaterId()) && sysWater.isAdmin())
        {
            throw new ServiceException("不允许操作超级管理员水泵");
        }
    }

    /**
     * 校验水泵是否有数据权限
     *
     * @param waterId 水泵id
     */
    @Override
    public void checkWaterDataScope(Long waterId)
    {
        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
        {
            SysWater sysWater = new SysWater();
            sysWater.setWaterId(waterId);
            List<SysWater> sysWaters = SpringUtils.getAopProxy(this).selectSysWaterList(sysWater);
            if (StringUtils.isEmpty(sysWaters))
            {
                throw new ServiceException("没有权限访问水泵数据！");
            }
        }
    }

    /**
     * 通过水泵ID查询水泵使用数量
     *
     * @param waterId 水泵ID
     * @return 结果
     */
    @Override
    public int countUserWaterByWaterId(Long waterId)
    {
        return userWaterMapper.countUserWaterByWaterId(waterId);
    }

    /**
     * 新增保存水泵信息
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertWater(SysWater sysWater)
    {
        // 新增水泵信息
        waterMapper.insertWater(sysWater);
        return insertWaterMenu(sysWater);
    }

    /**
     * 修改保存水泵信息
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateWater(SysWater sysWater)
    {
        // 修改水泵信息
        waterMapper.updateWater(sysWater);
        // 删除水泵与菜单关联
        waterMenuMapper.deleteWaterMenuByWaterId(sysWater.getWaterId());
        return insertWaterMenu(sysWater);
    }

    /**
     * 修改水泵状态
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    public int updateWaterStatus(SysWater sysWater)
    {
        return waterMapper.updateWater(sysWater);
    }

    /**
     * 修改数据权限信息
     *
     * @param sysWater 水泵信息
     * @return 结果
     */
    @Override
    @Transactional
    public int authDataScope(SysWater sysWater)
    {
        // 修改水泵信息
        waterMapper.updateWater(sysWater);
        // 删除水泵与渔场关联
        roleDeptMapper.deleteRoleDeptByRoleId(sysWater.getWaterId());
        // 新增水泵和渔场信息（数据权限）
        return insertWaterDept(sysWater);
    }

    /**
     * 新增水泵菜单信息
     *
     * @param sysWater 水泵对象
     */
    public int insertWaterMenu(SysWater sysWater)
    {
        int rows = 1;
        // 新增用户与水泵管理
        List<SysWaterMenu> list = new ArrayList<SysWaterMenu>();
        if(sysWater.getMenuIds() != null) {
            for (Long menuId : sysWater.getMenuIds()) {
                SysWaterMenu rm = new SysWaterMenu();
                rm.setWaterId(sysWater.getWaterId());
                rm.setMenuId(menuId);
                list.add(rm);
            }
        }
        if (list.size() > 0)
        {
            rows = waterMenuMapper.batchWaterMenu(list);
        }
        return rows;
    }

    /**
     * 新增水泵渔场信息(数据权限)
     *
     * @param sysWater 水泵对象
     */
    public int insertWaterDept(SysWater sysWater)
    {
        int rows = 1;
        // 新增水泵与渔场（数据权限）管理
        List<SysRoleDept> list = new ArrayList<SysRoleDept>();
        for (Long deptId : sysWater.getDeptIds())
        {
            SysRoleDept rd = new SysRoleDept();
            rd.setRoleId(sysWater.getWaterId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        if (list.size() > 0)
        {
            rows = roleDeptMapper.batchRoleDept(list);
        }
        return rows;
    }

    /**
     * 通过水泵ID删除水泵
     *
     * @param aerId 水泵ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteWaterById(Long aerId)
    {
        // 删除水泵与菜单关联
        aerationMenuMapper.deleteAerationMenuByAerId(aerId);
        // 删除水泵与渔场关联
        aerationDeptMapper.deleteAerationDeptByAerId(aerId);
        return  aerationMapper.deleteAerationById(aerId);
    }

    /**
     * 批量删除水泵信息
     *
     * @param waterIds 需要删除的水泵ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteWaterByIds(Long[] waterIds)
    {
        for (Long waterId : waterIds)
        {
            checkWaterAllowed(new SysWater(waterId));
            checkWaterDataScope(waterId);
            SysWater sysWater = selectWaterById(waterId);
            if (countUserWaterByWaterId(waterId) > 0)
            {
                throw new ServiceException(String.format("%1$s已分配,不能删除", sysWater.getWaterName()));
            }
        }
        // 删除水泵与菜单关联
        waterMenuMapper.deleteWaterMenu(waterIds);
        // 删除水泵与渔场关联
        waterDeptMapper.deleteWaterDept(waterIds);
        return waterMapper.deleteWaterByIds(waterIds);
    }

    /**
     * 取消授权用户水泵
     *
     * @param userWater 用户和水泵关联信息
     * @return 结果
     */
    @Override
    public int deleteUserWater(SysUserWater userWater)
    {
        return userWaterMapper.deleteUserWaterInfo(userWater);
    }

    /**
     * 批量取消授权用户水泵
     *
     * @param waterId 水泵ID
     * @param userIds 需要取消授权的用户数据ID
     * @return 结果
     */
    @Override
    public int deleteDeptWaters(Long waterId, Long[] userIds)
    {
        return userWaterMapper.deleteUserWaterInfos(waterId, userIds);
    }

    /**
     * 批量选择授权用户水泵
     *
     * @param waterId 水泵ID
     * @param userIds 需要授权的用户数据ID
     * @return 结果
     */
    @Override
    public int insertDeptWaters(Long waterId, Long[] userIds)
    {
        // 新增用户与水泵管理
        List<SysUserWater> list = new ArrayList<SysUserWater>();
        for (Long userId : userIds)
        {
            SysUserWater ur = new SysUserWater();
            ur.setUserId(userId);
            ur.setWaterId(waterId);
            list.add(ur);
        }
        return userWaterMapper.batchUserWater(list);
    }
}
